//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: setting.c 757 2007-05-10 08:19:31Z roger $
//

/* setting directory $HOME/.unihan2 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>

#include "setting.h"
#include "global.h"

gchar *get_home_dir(void);

static GList *IM_list_dup(GList *list);
static char *get_im_name_by_id(GList *im_all_list, char *id);
static GList *Symbol_retrieve_list(const gchar *string);
static GList *Word_retrieve_list(const gchar *string);
static GList *IM_get_default_im_list_from_all_list(GList *im_all_list);

#define DEFAULT_IM_LIST_PATH "/usr/share/unihan2/DefaultIM/"
#define DEFAULT_IM_LIST_CN "DefaultIMList.zh_CN"
#define DEFAULT_IM_LIST_HK "DefaultIMList.zh_HK"
#define DEFAULT_IM_LIST_TW "DefaultIMList.zh_TW"

GList *
get_curr_list_by_im_all_list(GList *im_all_list)
{
	gchar *home;
	char listFileName[256];
	char bufIMName[256];
	FILE *pListFile;
	GList *im_list = NULL;

	home = get_home_dir();

	if (!home) {
		return NULL;
	}

	memset(listFileName, 0, sizeof(listFileName));

	strcpy(listFileName, (char *)home);
	strcat(listFileName, UNIHAN_SETTING_DIR);
	if (access(listFileName, F_OK) != 0)
		mkdir(listFileName, 0755); 
	strcat(listFileName, IM_LIST_CURR_FILE);

	pListFile = fopen(listFileName, "r");
	if (!pListFile) {
		im_list = IM_get_default_im_list_from_all_list(im_all_list);
		if (!im_list)
			im_list = IM_list_dup(im_all_list);
		configure_im_list_file_by_im_list(im_list);
		return im_list;
	}

	while (fscanf(pListFile, "%s", bufIMName) != EOF) {
		IMInfo *info;

		info = g_new0(IMInfo, 1);
		info->id = strdup(bufIMName);
		info->cname = get_im_name_by_id(im_all_list, info->id);

		if (info->cname) {
			im_list = g_list_append(im_list, info);
		}
	}

	if (!im_list) {
		im_list = IM_list_dup(im_all_list);
		configure_im_list_file_by_im_list(im_list);
	}

	fclose(pListFile);
	return im_list;
}

gchar *
get_home_dir(void)
{
	gchar *p;
	p = g_strdup(g_get_home_dir());
	return p;
}

static char *
get_im_name_by_id(GList *im_all_list, char *id)
{
	char *name = NULL;
	GList *pIM = im_all_list;
	IMInfo *info;

	while(pIM) {
		info = (IMInfo *)pIM->data;
		if (!strcmp(info->id, id)) {
			name = strdup(info->cname);
			break;
		}
		pIM = g_list_next(pIM);
	}
	return name; 
}

void
free_im_list(GList *list)
{
	GList *l = list;

	while(l) {
		IMInfo *info = (IMInfo *)l->data;
		g_free(info->id);
		g_free(info->cname);
		l = g_list_next(l);
	}
	g_list_free(list);
}

void
configure_im_list_file_by_im_list(GList *list)
{
	FILE *pf;
	GList *l = list;
	char *home = get_home_dir();
	char path[256];

	sprintf(path, "%s%s%s", home, UNIHAN_SETTING_DIR, IM_LIST_CURR_FILE);
	pf = fopen(path, "w");
	if (!pf)
		return;
	while (l) {
		IMInfo *info;
		info = (IMInfo *)l->data;
		fprintf(pf, "%s\n", info->id);
		l = g_list_next(l);
	}
	fclose(pf);
}

static GList *
IM_list_dup(GList *list)
{
	GList *l = NULL;
	IMInfo *info = NULL;
	GList *l2 = list;
	IMInfo *info2 = NULL;

	while (l2) {
		info2 = (IMInfo *)l2->data;

		info = g_new0(IMInfo, 1);
		info->id = g_strdup(info2->id);
		info->cname = g_strdup(info2->cname);

		l = g_list_append(l, info);
		l2 = g_list_next(l2);
	}
	return l;
}

GList *
Symbol_get_list_from_conf_file(void)
{
	GList *l = NULL;
	FILE *pf;
	gchar *path;
	gchar modifier[5];
	gchar key[5];
	gchar symbol[9];

	path = g_strdup_printf("%s%s%s",
			get_home_dir(),
			UNIHAN_SETTING_DIR,
			SYMBOL_DEF_FILE);
	pf = fopen(path, "r");
	if (!pf)
		return NULL;

	while (fscanf(pf, "%s %s %s", modifier, key, symbol) != EOF) {
		SymDefGroup *pSDG = NULL;

		pSDG = g_new0(SymDefGroup, 1);
		pSDG->modifier = atoi(modifier);
		pSDG->key = atoi(key);
		pSDG->symbol = g_strdup(symbol);

		l = g_list_append(l, pSDG);
	}
	fclose(pf);
	return l;
}

void
Symbol_free_list(GList *list)
{
	return;
}

gboolean
Symbol_conf_file_by_symbol_list(GList *list)
{
	FILE *pf;
	gchar *path;
	gchar *item;
	GList *l = list;
	SymDefGroup *pSDG = NULL;

	path = g_strdup_printf("%s%s%s",
			get_home_dir(),
			UNIHAN_SETTING_DIR,
			SYMBOL_DEF_FILE);
	pf = fopen(path, "w");
	if (!pf)
		return FALSE;
	
	while (l) {
		pSDG = (SymDefGroup *)l->data;
		item = g_strdup_printf("%d %d %s\n",
				pSDG->modifier,
				pSDG->key,
				pSDG->symbol);
		fprintf(pf, "%s", item);
		l = g_list_next(l);
	}
	fclose(pf);
	return TRUE;
}

GList *
Symbol_get_new_list_from_prefedit(void)
{
	GtkSelectionData *seldata;
	int num;
	GList *l = NULL;

	seldata = gtk_clipboard_wait_for_contents(prefedit_clipboard,
			gdk_atom_intern("_SYMBOL_LIST", FALSE));
	if (!seldata)
		return NULL;

	num = atoi((char *)seldata->data);
	if (num < 1)
		return NULL;

	l = Symbol_retrieve_list((gchar *)seldata->data);
	gtk_selection_data_free(seldata);
	return l;
}

static GList *
Symbol_retrieve_list(const gchar *string)
{
	gchar **list_str = NULL;
	int num, i;
	GList *l = NULL;

	list_str = g_strsplit(string, "\n", 0);
	num = atoi(list_str[0]);
	for (i=0; i<num; i++) {
		SymDefGroup *pSDG = g_new0(SymDefGroup, 1);

		pSDG->modifier = atoi(list_str[i*3 + 1]);
		pSDG->key = atoi(list_str[i*3 + 2]);
		pSDG->symbol = g_strdup(list_str[i*3 + 3]);
		l = g_list_append(l, pSDG);
	}
	g_strfreev(list_str);
	return l;
}


GList *
Word_get_list_from_conf_file()
{
	GList *l = NULL;
	FILE *pf;
	gchar *path;
	gchar key[50];
	gchar word[100];

	path = g_strdup_printf("%s%s%s",
			get_home_dir(),
			UNIHAN_SETTING_DIR,
			WORD_DEF_FILE);
	pf = fopen(path, "r");
	if (!pf)
		return NULL;

	while (fscanf(pf, "%s %s", key, word) != EOF) {
		WordDefGroup *pWDG;
		pWDG = g_new0(WordDefGroup, 1);
		pWDG->key = g_strdup(key);
		pWDG->word = g_strdup(word);

		l = g_list_append(l, pWDG);
	}
	fclose(pf);
	return l;
}

void
Word_free_list(GList *list)
{
	return;
}

gboolean
Word_conf_file_by_word_list(GList *list)
{
	FILE *pf;
	gchar *path;
	gchar *item;
	GList *l = list;
	WordDefGroup *pWDG = NULL;

	path = g_strdup_printf("%s%s%s",
			get_home_dir(),
			UNIHAN_SETTING_DIR,
			WORD_DEF_FILE);
	pf = fopen(path, "w");
	if (!pf)
		return FALSE;

	while (l) {
		pWDG = (WordDefGroup *)l->data;
		item = g_strdup_printf("%s %s\n",
				pWDG->key,
				pWDG->word);
		fprintf(pf, "%s", item);
		l = g_list_next(l);
	}
	fclose(pf);
	return TRUE;
}

GList *
Word_get_new_list_from_prefedit(void)
{
	GtkSelectionData *seldata;
	int num;
	GList *l;

	seldata = gtk_clipboard_wait_for_contents(prefedit_clipboard,
			gdk_atom_intern("_WORD_LIST", FALSE));

	if (!seldata)
		return NULL;

	num = atoi((char *)seldata->data);
	if (num < 1)
		return NULL;

	l = Word_retrieve_list((gchar *)seldata->data);
	gtk_selection_data_free(seldata);
	return l;
}

static GList *
Word_retrieve_list(const gchar *string)
{
	gchar **list_str = NULL;
	int num, i;
	GList *l = NULL;

	list_str = g_strsplit(string, "\n", 0);
	num = atoi(list_str[0]);
	for (i=0; i<num; i++) {
		WordDefGroup *pWDG = g_new0(WordDefGroup, 1);

		pWDG->key = g_strdup(list_str[i*2 + 1]);
		pWDG->word = g_strdup(list_str[i*2 + 2]);
		l = g_list_append(l, pWDG);
	}
	g_strfreev(list_str);
	return l;
}

static GList *
IM_get_default_im_list_from_all_list(GList *im_all_list)
{
	FILE *pf = NULL;
	GList *im_list = NULL;
	char bufIMName[256];
	char filename[500];
	char *lang;

	memset(filename, 0, 500);
	lang = getenv("LANG");
	if (strstr(lang, "zh_CN")) {
		strcpy(filename, DEFAULT_IM_LIST_PATH);
		strcat(filename, DEFAULT_IM_LIST_CN);
	} else if (strstr(lang, "zh_HK")) {
		strcpy(filename, DEFAULT_IM_LIST_PATH);
		strcat(filename, DEFAULT_IM_LIST_HK);
	} else if (strstr(lang, "zh_TW")) {
		strcpy(filename, DEFAULT_IM_LIST_PATH);
		strcat(filename, DEFAULT_IM_LIST_TW);
	}

	if (!strlen(filename))
		return NULL;
	pf = fopen(filename, "r");
	if (!pf)
		return NULL;

	while (fscanf(pf, "%s", bufIMName) != EOF) {
		IMInfo *info;

		info = g_new0(IMInfo, 1);
		info->id = strdup(bufIMName);
		info->cname = get_im_name_by_id(im_all_list, info->id);

		if (info->cname) {
			im_list = g_list_append(im_list, info);
		}
	}

	return im_list;
}

// vi:ts=4:nowrap:cin:expandtab
